/*
 * HMM.h
 *
 *  Created on: 03.11.2011
 *	  Author: pavel
 */

#ifndef HMM_H_
#define HMM_H_

#include <vector>
#include <string>

typedef std::vector<unsigned> Observation;

class HMM {
private:
	unsigned n;
	unsigned m;
	std::vector<double> pi;
	std::vector<std::vector<double> > a;
	std::vector<std::vector<double> > b;
	std::string name;
	double eps;
	double delta;
	unsigned maxIter;
	
public:
	HMM();
	HMM(double eps);
	HMM(unsigned n, unsigned m);
	HMM(unsigned n, unsigned m,
	const std::vector<double> &pi,
	const std::vector<std::vector<double> > &a,
	const std::vector<std::vector<double> > &b);
	

	void init(unsigned n, unsigned m);
	void initRandom(unsigned n, unsigned m);
	void initEvenly(unsigned n, unsigned m);
	void initLRB(unsigned n, unsigned m, double p);

	void train(const Observation &obs);
	void train(const std::vector<Observation> &obs);
	void train(const HMM &source, unsigned tmax);

	void generate(Observation &obs) const;

	double logProb(const Observation &obs) const;

	void findMostProbablePath(const Observation &obs,
							   std::vector<unsigned> &path) const;

	void setNumberOfStates(unsigned n);
	void setAlphabetSize(unsigned m);
	
	void setEps(double eps);
	double getEps();
	
	unsigned getNumberOfStates() const;
	unsigned getAlphabetSize() const;
	
	double piAt(unsigned i) const;
	double aAt(unsigned i, unsigned j) const;
	double bAt(unsigned i, unsigned j) const;

	void print();
	
	virtual ~HMM();
};

#endif /* HMM_H_ */
